﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using System.Web.Security;
using MvcApplication2.Models;

namespace MvcApplication2
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : HttpApplication
    {
        public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new HandleErrorAttribute());
        }

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            // routes.MapRoute("DefaultLocalized",
            //  "{lang}/{controller}/{action}/{id}",
            //  new
            //  {
            //      controller = "Home",
            //      action = "Index",
            //      id = "",
            //  },
            //  new { lang = "[a-z]{2}" }
            //);


            routes.MapRoute(
            "Default",
            "{controller}/{action}/{id}",
            new { controller = "Home", action = "Index", id = "" }
            );

            routes.MapRoute(
                name: "TestExercise",
                url: "TestExercise/{side}/{action}/{id}",
                defaults: new { controller = "TestExercise", action = "Index", id = UrlParameter.Optional, side = UrlParameter.Optional }
            );

            routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );

            //routes.MapRoute(
            //    name: "Default",
            //    url: "{controller}/{action}/{id}",
            //    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            //);


        }

        protected void Application_Start()
        {
            //Database.SetInitializer<MvcApplication2Context>(null);
            Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MvcApplication2Context>());
            Thread l = new Thread(() => DummyData.AddDummyData(false));
            l.Start();

            ///this.AcquireRequestState
            //DummyData.AddDummyData();
            AreaRegistration.RegisterAllAreas();


            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);

            BundleTable.Bundles.RegisterTemplateBundles();
        }

        ///// <summary>
        ///// Sets a user's Locale based on the browser's Locale setting. If no setting
        ///// is provided the default Locale is used.
        ///// </summary>
        //public static void SetUserLocale(string CurrencySymbol, bool SetUiCulture)
        //{
        //    HttpRequest Request = HttpContext.Current.Request;
        //    if (Request.UserLanguages == null)
        //        return;

        //    string Lang = Request.UserLanguages[0];
        //    if (Lang != null)
        //    {
        //        // *** Problems with Turkish Locale and upper/lower case
        //        // *** DataRow/DataTable indexes
        //        if (Lang.StartsWith("tr"))
        //            return;

        //        if (Lang.Length < 3)
        //            Lang = Lang + "-" + Lang.ToUpper();
        //        try
        //        {
        //            System.Globalization.CultureInfo Culture = new System.Globalization.CultureInfo(Lang);
        //            if (CurrencySymbol != null && CurrencySymbol != "")
        //                Culture.NumberFormat.CurrencySymbol = CurrencySymbol;

        //            Thread.CurrentThread.CurrentCulture = Culture;

        //            if (SetUiCulture)
        //                Thread.CurrentThread.CurrentUICulture = Culture;
        //        }
        //        catch
        //        { ;}
        //    }
        //}

        public override void Init()
        {
            // Se voglio localizzare tramite cookie decomento questo.
            this.BeginRequest += MvcApplication_BeginRequest;

            base.Init();
        }

        bool IsValidCultureName(string cultureName)
        {
            return CultureInfo.GetCultures(CultureTypes.AllCultures)
            .Any(ci => ci.Name == cultureName);
        }

        void MvcApplication_BeginRequest(object sender, EventArgs e)
        {
            var langCookie = HttpContext.Current.Request.Cookies["lang"];

            CultureInfo ci = null;
            if (langCookie == null)
            {
                if (HttpContext.Current.Request.UserLanguages != null && HttpContext.Current.Request.UserLanguages.Length != 0)
                {
                    //Gets accepted list 
                    var langName = HttpContext.Current.Request.UserLanguages[0].Substring(0, 2);


                    langCookie = new HttpCookie("lang", langName)
                                     {
                                         HttpOnly = true
                                     };


                    HttpContext.Current.Response.AppendCookie(langCookie);
                }
            }

            if (langCookie != null)
            {
                var lang = langCookie.Value;

                if (!IsValidCultureName(lang))
                    lang = "en";

                ci = new CultureInfo(lang);
            }
            //Finally setting culture for each request
            if (ci == null) return;

            Thread.CurrentThread.CurrentUICulture = ci;
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture(ci.Name);
        }
    }

    public static class DummyData
    {
        private static MembershipUser GetUser(string username)
        {
            var user = Membership.GetUser(username) ?? Membership.CreateUser(username, "localhost", "fake@mail.com");

            return user;
        }

        private static void SetRandomLanguage(UserProfile profile, MvcApplication2Context db, Random random, int languageCnt)
        {
            var languageOwn = random.Next(1, languageCnt);

            for (int i = 0; i < languageOwn; i++)
            {
                var languageRandomIndex = random.Next(0, languageCnt);

                profile.Languages.Add(db.Languages.Find(languageRandomIndex));
            }
        }

        private static void SetRandomDevice(UserProfile profile, MvcApplication2Context db, Random random, int deviceCnt)
        {
            var deviceOwn = random.Next(1, deviceCnt);

            for (int i = 0; i < deviceOwn; i++)
            {
                var deviceRandomIndex = random.Next(0, deviceCnt);

                profile.Devices.Add(db.Devices.Find(deviceRandomIndex));
            }
        }

        /// <summary>
        /// Aggiunge dati nel database quando vengono cancellati
        /// </summary>
        public static void AddDummyData(bool destroy = false)
        {
            using (var db = new MvcApplication2Context())
            {
                if (destroy)
                {
                    db.Database.Delete();
                    db.SaveChanges();

                }
                // Controllo presenza data
                if (db.UsersProfiles.Any()) return;

                // Linguaggi
                var itaLang = new Language() { Description = "ITA" };
                db.Languages.Add(itaLang);
                var engLang = new Language() { Description = "ENG" };
                db.Languages.Add(engLang);
                var spaLang = new Language() { Description = "SPA" };
                db.Languages.Add(spaLang);
                var tedLang = new Language() { Description = "TED" };
                db.Languages.Add(tedLang);

                var pcDevice = new Device() { Description = "PC" };
                db.Devices.Add(pcDevice);
                //var iphoneDevice = new Device() { Description = "IPHONE" };
                //db.Devices.Add(iphoneDevice);
                //var androidDevice = new Device() { Description = "ANDROID" };
                //db.Devices.Add(androidDevice);
                //var tablet = new Device() { Description = "TABLET" };
                //db.Devices.Add(tablet);

                db.SaveChanges();

                var random = new Random(DateTime.Now.Second);

                const int testerCount = 5;

                var languageCount = db.Languages.Count();
                var deviceCount = db.Devices.Count();

                //Some Tester
                for (int i = 0; i < testerCount; i++)
                {
                    var uName = string.Format("{0}_{1}", "Tester", i);

                    var user = GetUser(uName);

                    var profile = new UserProfile()
                    {
                        DisplayName = user.UserName,
                        MembershipGuid = (Guid)user.ProviderUserKey,
                        AcceptTestingRequest = true,
                        CanPcScreencast = true,
                        CanRegisterMobileDevice = true,
                        Type = "tester"
                    };

                    SetRandomLanguage(profile, db, random, languageCount);

                    SetRandomDevice(profile, db, random, deviceCount);

                    db.UsersProfiles.Add(profile);
                }

                const int devCount = 5;
                const int exercisePerDev = 5;


                var exerciseStatus = new List<string> { "draft", "published" };

                var exerciseTestArray = new List<string>
                                        {
                                            ExerciseStatusType.Completed,
                                            ExerciseStatusType.Eliminated,
                                            ExerciseStatusType.ProposalActive,
                                            ExerciseStatusType.Rejected,
                                            ExerciseStatusType.WaitingPayment,
                                            ExerciseStatusType.WaitingTest
                                        };

                //Some dev 
                for (int i = 0; i < devCount; i++)
                {
                    var uName = string.Format("{0}_{1}", "Dev", i);

                    var user = GetUser(uName);

                    var profile = new UserProfile()
                    {
                        MembershipGuid = (Guid)user.ProviderUserKey,
                        AcceptTestingRequest = false,
                        CanPcScreencast = false,
                        CanRegisterMobileDevice = false,
                        Type = "dev"
                    };

                    SetRandomLanguage(profile, db, random, languageCount);

                    for (int j = 0; j < exercisePerDev; j++)
                    {
                        var exeName = string.Format("exercise_{0}_{1}", uName, j);

                        var statusRandomIndex = random.Next(0, exerciseStatus.Count);

                        // appare solamente draft.
                        var deviceRandomIndex = random.Next(0, db.Devices.Count());

                        var dev = db.Devices.ToList();

                        var exercise = new Exercise { Owner = profile, Title = exeName, Status = exerciseStatus[statusRandomIndex], Device = dev[deviceRandomIndex] };

                        db.Exercises.Add(exercise);
                    }

                    db.UsersProfiles.Add(profile);
                }

                db.SaveChanges();
            }

        }
    }
}
